package model;

import java.util.ArrayList;
import java.util.List;

import math.RMSE;
import data.Data;
import data.DataPredict;

public class Predict {
	List<DataPredict> list = new ArrayList<DataPredict>();
	
	public Predict(List<Data> test, MF mf){
		int k = mf.getK();
		double avg = mf.getAvgTrain();
		double[] ubias = mf.getUbias();
		double[] ibias = mf.getIbias();
		double[] ufactor = mf.getUfactor();
		double[] ifactor = mf.getIfactor();
		
		for(Data data : test){
			int uid = data.uid;
			short iid = data.iid;
			byte rat = data.rat;
			
			double pred = 0;
			pred += avg;
			pred += ubias[uid-1];
			pred += ibias[iid-1];
			
			for(int j=0; j<k; j++){
				pred += ufactor[(uid-1)*k+j]*ifactor[(iid-1)*k+j];
			}
			
			list.add(new DataPredict(uid,iid,pred));
		}
		
		System.out.println("RMSE "+RMSE.RMSE(test, avg, ubias, ibias, ufactor, ifactor, k));
	}
	
	public Predict(List<Data> postest, List<Data> negtest, List<Data> neutest, MF mf, MF pmf, MF nmf){
		int k = mf.getK();
		double avg = mf.getAvgTrain();
		double[] ubias = mf.getUbias();
		double[] ibias = mf.getIbias();
		double[] ufactor = mf.getUfactor();
		double[] ifactor = mf.getIfactor();

		double pavg = pmf.getAvgTrain();
		double[] uposbias = pmf.getUbias();
		double[] iposbias = pmf.getIbias();
		double[] uposfactor = pmf.getUfactor();
		double[] iposfactor = pmf.getIfactor();		

		double navg = nmf.getAvgTrain();
		double[] unegbias = nmf.getUbias();
		double[] inegbias = nmf.getIbias();
		double[] unegfactor = nmf.getUfactor();
		double[] inegfactor = nmf.getIfactor();
		
		for(Data data : postest){
			int uid = data.uid;
			short iid = data.iid;
			byte rat = data.rat;
			
			double pred = 0;
			pred += pavg;
			pred += uposbias[uid-1];
			pred += iposbias[iid-1];
			
			for(int j=0; j<k; j++){
				pred += uposfactor[(uid-1)*k+j]*iposfactor[(iid-1)*k+j];
			}
			
			list.add(new DataPredict(uid,iid,pred));
		}
		
		for(Data data : neutest){
			int uid = data.uid;
			short iid = data.iid;
			byte rat = data.rat;
			
			double pred = 0;
			pred += avg;
			pred += ubias[uid-1];
			pred += ibias[iid-1];
			
			for(int j=0; j<k; j++){
				pred += ufactor[(uid-1)*k+j]*ifactor[(iid-1)*k+j];
			}
			
			list.add(new DataPredict(uid,iid,pred));
		}
		
		for(Data data : negtest){
			int uid = data.uid;
			short iid = data.iid;
			byte rat = data.rat;
			
			double pred = 0;
			pred += navg;
			pred += unegbias[uid-1];
			pred += inegbias[iid-1];
			
			for(int j=0; j<k; j++){
				pred += unegfactor[(uid-1)*k+j]*inegfactor[(iid-1)*k+j];
			}
			
			list.add(new DataPredict(uid,iid,pred));
		}
		
		System.out.println("RMSE "+RMSE.RMSE(postest, negtest, neutest, avg, ubias, ibias, ufactor, ifactor, 
				pavg, uposbias, iposbias, uposfactor, iposfactor, 
				navg, unegbias, inegbias, unegfactor, inegfactor, k));
		
	}
}
